﻿using SimpleInjector;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.AbstractClassesAndInterfaces;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.EsgResearchProfileLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.IndicatorTemplateLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPIndicatorExtendedLogic;
using Sustainalytics.Entities;
using Sustainalytics.Events.DataAccessLayer;
using Sustainalytics.MongoDB.Extensions;
using Sustainalytics.SharedEntities.EsgResearch;
using Sustainalytics.SharedEntities.EsgResearch.PartialEsgResearch;
using Sustainalytics.Synchronization.Interface;
using System;
using System.Collections.Generic;
using System.Configuration.Abstractions;
using System.Linq;

namespace Sustainalytics.ClientDW.Synchronization.SyncESGData
{
    public static class SimpleInjectorConfig
    {
        public static Container Register(ILogger logger, Dictionary<string, string> gaConnectionStrings)
        {
            var container = new Container();

            container.RegisterCollections(gaConnectionStrings);

            container.RegisterMisc(logger, gaConnectionStrings["EventsConnectionString"]);

            container.Verify();

            return container;
        }

        private static void RegisterCollections(this Container container, Dictionary<string, string> gaConnectionStrings)
        {
            var clientDwConnectionString = gaConnectionStrings["ClientDW"];
            var dwArchiveConnectionString = gaConnectionStrings["DWArchive"];

            container.Register(() => MongoFactory.GetCollectionFromDatabase<CompanyProfileResearchState>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RPCompanyProfile>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Analyst>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<CompanyWeights>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<EsgResearchProfile>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<IndicatorTemplate>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ESG.Entities.RPCompanyESGComputationResult>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RPIndicatorExtended>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Source>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<WeightMatrix>(clientDwConnectionString));

            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.ClientDW.Entities.CorporateData>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.ESG.Entities.CompanyKeyESGIssue>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.ESG.Entities.SubPeerGroupKeyEsgIssue>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.Entities.CompanyHistoricalDataIndicators>(dwArchiveConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.Entities.ESGRatings.EsgFocusThresholds>(clientDwConnectionString));
        }

        private static void RegisterMisc(this Container container, ILogger logger, string eventsConnectionString)
        {
            container.Register(() => logger, Lifestyle.Singleton);

            container.RegisterSingleton(() => ConfigurationManager.Instance.AppSettings);
            container.RegisterSingleton<BackOfficeAppSettings>();
            container.RegisterSingleton(() => new ResearchDataProvider.ResearchDataProvider(new Ai.HbaseRepository.HbaseConfiguration
            {
                ThriftServerAddress = container.GetInstance<BackOfficeAppSettings>().ThriftServer,
                ThriftPort = container.GetInstance<BackOfficeAppSettings>().ThriftPort,
                TablePrefix = container.GetInstance<BackOfficeAppSettings>().HbaseTablePrefix, 
            }));
            container.Register<EsgResearchProfileQuery>(Lifestyle.Singleton);

            container.Register<IComprehensiveEsgIndicatorTemplateQuery, IndicatorTemplateQuery>(Lifestyle.Singleton);
            container.RegisterSingleton(() => container.GetInstance<IComprehensiveEsgIndicatorTemplateQuery>().Get());
            container.RegisterSingleton(() => container.GetInstance<List<IndicatorTemplate>>().Select(it => new IndicatorTemplate
            {// create new IndicatorTemplates without AnswerCategories as this collection is not necessary for instance indicators which will search this dictionary based on indicator number
                Id = it.Id,
                Name = it.Name,
                Number = it.Number,
                SortKey = it.SortKey,
                ThemeId = it.ThemeId,
                ThemeName = it.ThemeName,
                ThemeSortKey = it.ThemeSortKey,
                IndicatorCategory = it.IndicatorCategory,
                IndicatorCategorySortKey = it.IndicatorCategorySortKey,
                IsControversyIndicator = it.IsControversyIndicator
            }).ToDictionary(it => it.Number));

            container.Register<CompanyHistoricalDataIndicatorsQuery>();
            container.RegisterSingleton(() => container.GetInstance<CompanyHistoricalDataIndicatorsQuery>().Get().Result);
            container.RegisterSingleton(() => new EventsDatabase(eventsConnectionString, (int)TimeSpan.FromHours(1).TotalSeconds));
        }
    }
}
